<?php
// 接口-工序报工接口
namespace interface\v1;

use verify;

class processReportClass extends index
{
	private const table       = 'process_report';
	private const tableMx     = 'process_report_detail';
	private const tableStaff  = 'process_report_staff';
	private const page        = 'processReport';
	private const title       = '工序报工';
	private const stateOption = ['草稿', '待确认', '已确认'];
	
	public function search()
	{
		$this->code         = 1;
		$this->resp['data'] = [
			'orderBy' => [
				'创建时间降序',
				'创建时间升序',
				'计划开始时间降序',
				'计划开始时间升序',
				'计划完工时间降序',
				'计划完工时间升序',
			],
			'search'  => [
				[
					'key'   => 'type',
					'name'  => '加工单类型',
					'array' => ['生产加工', '生产返工'],
				],
				[
					'key'   => 'line',
					'name'  => '生产线',
					'array' => find([
						'table' => 'product_line',
						'field' => "id as value, name as text ",
						'where' => "coid = '" . self::$coid . "'",
					])['array'],
				],
				[
					'key'   => 'startTime',
					'name'  => '计划开始时间',
					'array' => [
						'今天', '近7天', '近30天', '自定义',
					],
				],
				[
					'key'   => 'state',
					'name'  => '状态',
					'array' => self::stateOption,
				],
			],
		];
	}
	
	/**
	 * 列表
	 *
	 * @return void
	 */
	public function list(): void
	{
		$and   = "";
		$equal = [
			'coid'  => self::$coid,
			'state' => $this->post('state'),
		];
		//like查询数组
		$like = [
			"orderNo" => $this->post('orderNo'),//单据编号
		];
		//初始化
		$mwhere = search([
			'=' => [
				'type'   => $this->post('type'),
				'lineId' => $this->post('line'),
			],
		]);
		if ($mwhere) {
			$and .= " AND sendId In (SELECT id FROM machining_send_order WHERE 1=1 $mwhere )";
		}
		// 计划时间
		if ($this->post('startTime')) {
			$and .= self::miniTimeComparison($this->post('startTime'), 'date', 'startTime');
		}
		//如果没有查看所有员工请假记录的权限
		if (!$this->power(self::page, "seeAll")) {
			$and .= $this->seeSelf(self::page);
		}
		//获取查询结果
		$where        = search(["like" => $like, "=" => $equal]) . $and;
		$orderBy      = $this->post('orderBy') ?: '创建时间降序';
		$orderByArray = $this->orderBy([
			"search"  => $orderBy,
			"default" => "创建时间降序",
			"array"   => [
				"time"       => ["asc" => "创建时间升序", "desc" => "创建时间降序", "site" => 1],
				"recordDate" => ["asc" => "单据时间升序", "desc" => "单据时间降序", "site" => 2],
			],
		]);
		$page         = $this->page(["table" => self::table, "where" => $where, "order" => $orderByArray['orderBy']]);
		//数据分析
		$data['result'] = [];
		foreach ((array)$page['array'] as $array) {
			$machiningSendOrder = query('machining_send_order', "id = '$array[sendId]'");
			$line               = query('product_line', "id = '$machiningSendOrder[lineId]'");
			$process            = query('process', "id = '$array[processId]'");
			$material           = query('material', "id = '$array[materialId]'");
			$materialSku        = query('material_sku', "id = '$array[materialSkuId]'");
			$data['result'][]   = [
				"id"               => $array['id'],
				'orderNo'          => $array['orderNo'],
				'MachiningorderNo' => $machiningSendOrder['orderNo'],
				'line'             => $line['workshop'] . ' - ' . $line['name'],
				'processName'      => $process['name'],
				'code'             => $material['code'],
				'brand'            => $material['brand'],
				'name'             => $material['name'],
				'model'            => $material['model'],
				'skuName'          => $materialSku['name'],
				'num'              => $array['yield'],
				'unit'             => $machiningSendOrder['unit'],
				'staffName'        => self::findStaff($array['stid']),
				'stid'             => $array['stid'],
				'state'            => $array['state'],
				'time'             => self::formatDate($array['time']),
			];
		}
		$data['page'] = $page['para'];
		//返回
		$this->code         = 1;
		$this->resp['data'] = $data;
	}
	
	
	/**
	 * 详情
	 *
	 * @return void
	 */
	public function detail(): void
	{
		$id   = $this->post('id');
		$info = query(self::table, "id = '" . $id . "'");
		if (empty($id)) {
			$this->resp['warn'] = "ID为空";
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = "未找到此" . self::title;
		} else {
			$audit              = find([
				'table' => 'auditing_follow',
				'where' => " typeId = '$info[id]' order by time desc",
			]);
			$machiningSendOrder = query('machining_send_order', "id = '$info[sendId]'");
			$machiningOrderMx   = query('machining_order_mx', "id = '$machiningSendOrder[machiningOrderMxId]'");
			$line               = query('product_line', "id = '$machiningSendOrder[lineId]'");
			$process            = query('process', "id = '$info[processId]'");
			$material           = query('material', "id = '$machiningSendOrder[materialId]'");
			$materialSku        = query('material_sku', "id = '$machiningSendOrder[materialSkuId]'");
			$bom                = query('bom', "id = '$machiningOrderMx[bomId]'");
			$routing            = query('routing', "id = '$machiningOrderMx[routingId]'");
			$team               = query('team', "id = '$info[teamId]'");
			$result             = find(['table' => self::tableMx, 'field' => " id, problem, num", 'where' => " orderId = '$info[id]' order by list asc"]);
			$detail             = [];
			foreach ($result['array'] as $item) {
				$detail[$item['id']] = $item;
			}
			$reportNum      = find(['table' => self::table, 'where' => " sendId = '$info[id]'", 'sum' => "yield"]);
			$data['result'] = [
				'info'        => [
					'id'                => $info['id'],
					'staffName'         => self::findStaff($info['stid']),
					'orderNo'           => $info['orderNo'],
					'workshop'          => $line['workshop'],
					'lineName'          => $line['name'],
					'lineNameAlias'     => $line['workshop'] . '-' . $line['name'],
					'processId'         => $process['id'],
					'processName'       => $process['name'],
					'valuationType'     => $info['valuationType'],
					'sendOrderNo'       => $machiningSendOrder['orderNo'],
					'sendOrderType'     => $machiningSendOrder['type'],
					'materialCode'      => $material['code'],
					'materialName'      => $material['name'],
					'model'             => $material['model'],
					'materialSkuName'   => $materialSku['name'],
					'materialNameAlias' => $material['code'] . '-' . $material['name'] . '-' . $material['model'] . '-' . $materialSku['name'],
					'num'               => $machiningSendOrder['num'],
					'planNum'           => floatval($machiningSendOrder['num']) . $machiningSendOrder['unit'],
					'reportNum'         => $reportNum. $machiningSendOrder['unit'],
					'unit'              => $machiningSendOrder['unit'],
					'bomVersion'        => $bom['bomVersion'],
					'roudescription'    => $routing['description'],
					'routext'           => $routing['text'],
					'startDate'         => $machiningSendOrder['startDate'],
					'endDate'           => $machiningSendOrder['endDate'],
					'startTime'         => $info['startTime'],
					'endTime'           => $info['endTime'],
					'text'              => $machiningSendOrder['text'],
					'state'             => $info['state'],
					'sendId'            => $machiningSendOrder['id'],
				],
				'reportWork'  => [
					'teamNo'    => $info['teamNo'],
					'teamType'  => $info['teamType'],
					'teamId'    => $team['id'],
					'teamName'  => $team['name'],
					'yield'     => floatval($info['yield']),
					'badNum'    => floatval($info['badNum']),
					'startTime' => $info['startTime'],
					'endTime'   => $info['endTime'],
					'text'      => $info['text'],
				],
				'problem'     => explode('，', $process['defectType']),
				'detail'      => $detail,
				'auditRecord' => $audit['array'],
			];
			//返回
			$this->code         = 1;
			$this->resp['data'] = $data;
		}
	}
	
	public function getMaterial()
	{
		$like   = [
			'orderNo' => $this->post('wd'),
		];
		$equal  = [
			'id'    => $this->post('id'),
			'coid'  => self::$coid,
			'state' => '已确认',
		];
		$where  = search(["like" => $like, "=" => $equal]);
		$page   = $this->page([
			"table"   => "machining_send_order",
			"where"   => $where,
			'pageNum' => 50,
			"order"   => "`time` ASC",
		]);
		$result = [];
		//获取记录
		foreach ($page['array'] as $array) {
			$material      = query('material', "id = '$array[materialId]'");
			$materialSku   = query('material_sku', "id = '$array[materialSkuId]'");
			$line          = query('product_line', "id = '$array[lineId]'");
			$process       = query('process', "id = '$array[processId]'");
			$routingDetail = query('routing_detail', "id = '$array[routingMxId]'");
			$reportNum     = find(['table' => self::table, 'where' => " sendId = '$array[id]'", 'sum' => "yield"]);
			$result[]      = [
				'sendId'            => $array['id'],
				'orderNo'           => $array['orderNo'],
				'time'              => self::formatDate($array['time'], 'Y-m-d H:i'),
				'lineNameAlias'     => $line['workshop'] . '-' . $line['name'],
				'materialNameAlias' => $material['code'] . '-' . $material['name'] . '-' . $material['model'] . '-' . $materialSku['name'],
				'processName'       => $process['name'],
				'valuationType'     => $routingDetail['valuationType'],
				'processId'         => $process['id'],
				'planNum'           => floatval($array['num']) . $array['unit'],
				'reportNum'         => floatval($reportNum) . $array['unit'],
				'problem'           => static::filterArray(explode('，', $process['defectType'])),
			];
		}
		$this->resp['data'] = [
			'result' => $result,
			'page'   => $page['para'],
		];
		$this->code         = 1;
	}
	
	public function edit()
	{
		$id         = $this->post('id') ?: self::getId();
		$detail     = !empty($_POST['detail']) ? json_decode($_POST['detail'], true) : [];
		$mxIdArr    = $this->post('mxId') ?: inStockClass::getArrVal('id', $detail);
		$problemArr = $this->post('problem') ?: inStockClass::getArrVal('problem', $detail);
		$numArr     = $this->post('num') ?: inStockClass::getArrVal('num', $detail);
		//赋值
		$field      = [
			"startTime" => $this->post('startTime'),
			"endTime"   => $this->post('endTime'),
			"sendId"    => $this->post('sendId'),//备注
			'teamNo'    => $this->post('teamNo'),
			"teamType"  => $this->post('teamType'),
			"teamId"    => $this->post('teamId'),
			"yield"     => $this->post('yield'),
			"badNum"    => $this->post('badNum'),
		];
		$annotation = [
			"sendId"   => '生产派工单',
			'teamNo'   => '班次',
			"teamType" => '班次',
			"teamId"   => '班组',
			"yield"    => '生产数量',
		];
		$rules      = [
			"sendId"   => 'required',
			'teamNo'   => 'required',
			"teamType" => 'required',
			"teamId"   => 'required',
			"yield"    => 'required|numeric',
		];
		// 校验是否符合规则
		$vt     = new verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$this->resp['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		$info = query(self::table, " id = '" . $id . "' ");
		//判断
		if (!$this->power(self::page, "edit")) {
			$this->resp['warn'] = "权限不足";
		} elseif ($info['state'] == '已确认') {
			$this->resp['warn'] = '此报工已确认，不能编辑';
		} else {
			$this->startTrans();
			$machiningSendOrder     = query('machining_send_order', "id = '$field[sendId]'");
			$field['materialId']    = $machiningSendOrder['materialId'];
			$field['materialSkuId'] = $machiningSendOrder['materialSkuId'];
			$field['processId']     = $machiningSendOrder['processId'];
			if (empty($info['id'])) {
				$userNo             = self::generateCode(self::page, [
					'prefix' => 'BG' . date('Ymd'),
					'table'  => self::table,
					'field'  => 'orderNo',
					'where'  => '',
				], $field);
				$field              = array_merge($field, [
					"id"      => $id, 'coid' => self::$coid,
					'orderNo' => $userNo,
					'state'   => '草稿',
					'stid'    => $this->control['stid'],
				]);
				$this->resp['warn'] = insert(["table" => self::table, "field" => $field]);
			} else {
				$this->resp['warn'] = update(["table" => self::table, "field" => $field, "where" => "id = '$info[id]'"]);
			}
			if (is_array($mxIdArr)) {
				foreach ($mxIdArr as $k => $mxId) {
					$mx = query(self::tableMx, "id = '$mxId'");
					if (!empty($mx['id'])) {
						$warn = static::update([
							'table' => self::tableMx,
							'field' => [
								'problem' => $problemArr[$k],
								'num'     => $numArr[$k],
							],
							'where' => "id = '$mx[id]'",
						]);
					} else {
						$warn = static::insert([
							'table' => self::tableMx,
							'field' => [
								'id'      => $mxId,
								'coid'    => self::$coid,
								'orderId' => $id,
								'problem' => $problemArr[$k],
								'num'     => $numArr[$k],
							],
						]);
					}
					if (!in_array($warn, ["新增成功", "更新成功"])) {
						$this->resp['warn'] = $warn;
						break;
					}
				}
			}
			if (!in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				$this->rollback();
			} else {
				$this->commitTrans();
				delete(['table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"]);
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "ID：" . $id;
				$this->logText(["type" => self::page, "text" => $text]);
				$this->resp['data'] = $id;
				//返回
				$this->code = 1;
			}
		}
		resp:
	}
	
	public function getTeamType()
	{
		$this->code         = 1;
		$this->resp['data'] = explode('，', para('teamType'));
	}
	
	public function getTeam()
	{
		$this->code         = 1;
		$this->resp['data'] = find(['table' => 'team', 'field' => 'id as value, name as text', 'where' => " coid = '" . self::$coid . "' AND state = '启用' "])['array'];
	}
	
	
	/**
	 * 计算BOM用料(主单位)
	 */
	public static function bomMx($bomId, $materialSkuId, $num, $unit, &$materialList = [])
	{
		$bom = query('bom', "id = '$bomId' and state = '启用'");
		if (empty($bom['id'])) {
			return '未找到BOM表';
		}
		$materialSku = query('material_sku', "id = '$materialSkuId'");//生产SKU
		$material    = query('material', "id = '$bom[materialId]'");
		//BOM表头物料单位向物料主单位转化
		if ($bom['unit'] == $material['unit_one']) {
			$bom['num'] = $material['unitOne'] * $bom['num'];
		} elseif ($bom['unit'] == $material['unit_two']) {
			$bom['num'] = $material['unitTwo'] * $bom['num'];
		} elseif ($bom['unit'] != $material['unit']) {
			return 'BOM表头物料单位不在物料的单位中';
		}
		//生产单位向主单位转化
		if ($unit == $material['unit']) {
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} elseif ($unit == $material['unit_one']) {
			$num = $num * $materialSku['unitOne'];
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} elseif ($unit == $material['unit_two']) {
			$num = $num * $materialSku['unitTwo'];
			$pcs = $bom['num'] > 0 ? ($num / $bom['num']) : 0;//需要几个BOM的子物料
		} else {
			return $materialList;
		}
		$bomMx = find(['table' => 'bom_detail', 'where' => "orderId = '$bom[id]' order by list"]);
		foreach ($bomMx['array'] as $array) {
			$materialList[] = ['materialId' => $array['materialId'], 'materialSkuId' => $array['materialSkuId'], 'loss' => $array['loss'], 'num' => $array['num'] * $pcs, 'unit' => $material['unit']];
		}
		return $materialList;
	}
	
	
	/**
	 * 提交
	 */
	public function commit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " id = '$id'");
		$field = [
			'state' => '待确认',
		];
		if (!$this->power(self::page, 'edit')) {
			$this->resp['warn'] = '你还没有编辑权限';
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = '未找到此工序报工';
		} elseif ($info['state'] != '草稿') {
			$this->resp['warn'] = '此工序报工不是草稿状态，不能提交';
		} else {
			$this->resp['warn'] = static::update([
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			]);
			if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				auditingFollow([
					"type"      => "工序报工",
					"typeId"    => $info['id'],
					"text"      => "【{$this->control['name']}】提交",
					'job'       => self::findStaffDepartment(self::$stid) . '-' . $this->controlJob['name'],
					'staffName' => $this->control['name'],
				]);
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$this->resp['warn'] = '提交成功';
				$this->code         = 1;
			}
		}
		resp:
	}
	
	/**
	 * 确认
	 */
	public function confirmEdit()
	{
		$id    = $this->post('id');
		$info  = query(self::table, " id = '$id'");
		$field = [
			'state'       => '已确认',
			'checkId'     => self::$stid,
			'confirmTime' => $this->time,
		];
		if (!$this->power(self::page, 'confirm')) {
			$this->resp['warn'] = '你还没有确认权限';
		} elseif (empty($info['id'])) {
			$this->resp['warn'] = '未找到此' . self::title;
		} elseif ($info['state'] != '待确认') {
			$this->resp['warn'] = '此' . self::title . '不是待确认状态，不能确认';
		} else {
			$this->startTrans();
			$this->resp['warn'] = update([
				"table" => self::table,
				"field" => $field,
				"where" => "id = '$info[id]'",
			]);
			$teamMx             = find(['table' => 'team_detail', "where" => "orderId = '$info[teamId]' order by list asc"]);
			foreach ($teamMx['array'] as $array) {
				$warn = static::insert([
					'table' => self::tableStaff,
					'field' => [
						'id'      => self::getId(),
						'orderId' => $info['id'],
						'stid'    => $array['stid'],
						'coid'    => self::$coid,
					],
				]);
				if ($warn != '新增成功') {
					$this->resp['warn'] = $warn;
					break;
				}
			}
			if (!in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
				$this->rollback();
			} else {
				$this->commitTrans();
				//生成出库单
				auditingFollow([
					"type"      => "工序报工",
					"typeId"    => $info['id'],
					"text"      => "【{$this->control['name']}】确认",
					'job'       => self::findStaffDepartment(self::$stid) . '-' . $this->controlJob['name'],
					'staffName' => $this->control['name'],
				]);
				//添加日志
				$type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$this->resp['warn'] = '确认成功';
				$this->code         = 1;
			}
		}
		resp:
	}
	
	/**
	 * 删除
	 *
	 * @return void
	 */
	public function delete(): void
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$this->resp['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$this->resp['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] == '已确认') {
					$warn = "删除失败：已确认，暂不能删除";
				} else {
					//最后删除基本参数
					delete(["table" => self::table, "where" => " id = '$id' "]);
					delete(["table" => self::tableMx, "where" => " orderId = '$id' "]);
					delete(["table" => 'auditing_follow', "where" => " typeId = '$id' "]);
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(["type" => self::page, "text" => $text]);
			$this->resp['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$this->code         = 1;
		}
	}
}

